interface PercentOption {
  min?: number;
  max?: number;
  minPercent?: number;
}

import Strings from '@/i18n';

const hex2Dec = (hex: string) => {
  return parseInt(hex, 16);
};

const orderArr = [
  [1, 10],
  [11, 19],
  [20, 29],
  [30, 42],
];

/**
 * 标准百分比计算公式
 * @param value 值
 * @param option 百分比计算配置
 */
export const formatPercent = (
  value = 0,
  { min = 0, max = 1000, minPercent = 0 }: PercentOption = {}
): number => {
  return Math.min(100, Math.round(((100 - minPercent) * (value - min)) / (max - min) + minPercent));
};

export const repeatArrtoStr = (originSource: number[]) => {
  if (!originSource) return '';
  const source = originSource.map(i => +i);

  const days: string[] = [];
  let repeat = '';
  let workDay = true;
  let weekend = true;
  source.forEach((item, index) => {
    if (index > 0 && index < 6) {
      if (item === 0) {
        workDay = false;
      }
    }
    if (index === 0 || index === 6) {
      if (item === 0) {
        weekend = false;
      }
    }
    if (item === 1) {
      days.push(Strings.getLang(`week${index}`));
    }
  });
  if (workDay && weekend) {
    repeat = Strings.getLang('daily');
  } else if (workDay && days.length === 5) {
    return Strings.getLang('workDay');
  } else if (weekend && days.length === 2) {
    return Strings.getLang('weekend');
  } else if (days.length === 0) {
    repeat = Strings.getLang('once');
  } else {
    repeat = days.join(' ');
  }
  return repeat;
};

const lampModeMap = {
  '00': 'lighting_lamp',
  '01': 'color_ligth',
  '02': 'breathe_lamp',
  lighting_lamp: '00',
  color_ligth: '01',
  breathe_lamp: '02',
};

const musiceSetMap = {
  '00': 'nature',
  '01': 'environment',
  '02': 'thing',
  '03': 'sleep',
  0: 'nature',
  1: 'environment',
  2: 'thing',
  3: 'sleep',
  nature: 0,
  environment: 1,
  thing: 2,
  sleep: 3,
};

const musiceSetStrMap = {
  '00': 'nature',
  '01': 'environment',
  '02': 'thing',
  '03': 'sleep',

  nature: '00',
  environment: '01',
  thing: '02',
  sleep: '03',
};

export const decodeClock = (str: string, code?: string) => {
  if (!str.length || str.length < 39)
    return {
      startTime: 480,
      music: 'ringtone_1',
      musicSet: 'nature',
      status: false,
      musicPower: true,
      lightMode: 'lighting_lamp',
      repeat: [1, 1, 1, 1, 1, 1, 1],
      wakeUp: false,
      advanceTime: 0,
      voice: 60,
      light: 33,
      colour: 0,
      lampPower: false,
      code: code,
      colourBright: 1000,
    };

  try {
    let i = 0;

    const power = str.slice(i, i + 2);
    i += 2;

    const startTime = str.slice(i, i + 4);
    i += 4;

    const repeat = str.slice(i, i + 2);

    const repeat1 = parseInt(repeat.slice(0, 1), 16)
      .toString(2)
      .padStart(4, '0')
      .split('')
      .map(item => +item);

    const repeat2 = parseInt(repeat.slice(1), 16)
      .toString(2)
      .padStart(4, '0')
      .split('')
      .map(item => +item);

    const orginWeek = [...repeat1, ...repeat2].reverse().slice(0, 7);

    i += 2;

    const lampPower = str.slice(i, i + 2);
    i += 2;

    const lampMode = str.slice(i, i + 2);

    // 00照明灯/01彩灯/02呼吸灯
    i += 2;

    const hue = str.slice(i, i + 4);
    i += 4;

    const saturation = 1000;
    i += 4;

    const brightness = str.slice(i, i + 4);
    i += 4;

    const light = str.slice(i, i + 4);
    i += 4;

    const musicPower = str.slice(i, i + 2);
    i += 2;

    const musictype = str.slice(i, i + 2);
    i += 2;

    const musicOrder = str.slice(i, i + 2);
    i += 2;

    const musicVolume = str.slice(i, i + 2);
    i += 2;

    const advancePower = str.slice(i, i + 2);
    i += 2;

    const advanceTime = str.slice(i, i + 2);

    return {
      status: power === '01',

      startTime: hex2Dec(startTime),

      repeat: orginWeek,

      lampPower: !!hex2Dec(lampPower),

      lightMode: lampModeMap[lampMode],

      colour: hex2Dec(hue),

      colourBright: hex2Dec(brightness),

      light: hex2Dec(light),

      musicPower: musicPower === '01',

      musicSet: musiceSetMap[musictype] ?? 'nature',

      music: `ringtone_${hex2Dec(musicOrder) + 1}`,

      wakeUp: advancePower === '01',

      advanceTime: hex2Dec(advanceTime),

      voice: hex2Dec(musicVolume),
    };
  } catch (error) {
    return {
      setted: false,
      colourBright: 1000,
      light: 1000,
      voice: 100,
    };
  }
};

export const findRangeIndex = (num: number): number => {
  return orderArr.findIndex(([start, end]) => num >= start && num <= end);
};

const number2hex = (number, length = 2) => {
  return number.toString(16).padStart(length, '0');
};

export const encodeClock = params => {
  const {
    musicPower,
    volumeSet,
    brightValue,
    startTime,
    weeks,
    wakeUp,
    advanceTime,
    lampPower,
    musicSet,
    ringtone,
    code,
    status,
    lightMode,
    colour,
    colourBright,
  } = params;

  const powerStr = status ? '01' : '00';

  const startTimeStr = number2hex(startTime, 4);

  const newWeeks = [...weeks, 0].reverse();

  const week1Str = parseInt(newWeeks.slice(0, 4).join(''), 2).toString(16);

  const week2Str = parseInt(newWeeks.slice(4).join(''), 2).toString(16);

  const weekStr = `${week1Str}${week2Str}`;

  const lampPowerStr = lampPower ? '01' : '00';

  const lampModeStr = lampModeMap[lightMode] || '00';

  const hueStr = number2hex(colour, 4);

  const saturation = '03e8';

  const brightness = number2hex(colourBright, 4);

  const lightStr = number2hex(brightValue, 4);

  const ringtoneNumber = +ringtone.replace('ringtone_', '');

  const musicPowerStr = musicPower ? '01' : '00';

  const musicSetStr = musiceSetStrMap[musicSet];

  const musicOrderStr = number2hex(ringtoneNumber - 1);

  const voiceStr = number2hex(volumeSet);

  const advancePowerStr = wakeUp ? '01' : '00';

  const advanceTimeStr = number2hex(wakeUp ? advanceTime : 0);

  return `${powerStr}${startTimeStr}${weekStr}${lampPowerStr}${lampModeStr}${hueStr}${saturation}${brightness}${lightStr}${musicPowerStr}${musicSetStr}${musicOrderStr}${voiceStr}${advancePowerStr}${advanceTimeStr}`;
};

export const encodeScene = params => {
  const {
    code = 'customize_scene_1',
    lampPower,
    lightMode,
    colour,
    brightValue,
    musicPower,
    musicSet,
    ringtone,
    volumeSet,
    colourBright,
  } = params;

  const powerStr = lampPower ? '01' : '00';

  const lightModeStr = lampModeMap[lightMode] || '00';

  const hueStr = number2hex(colour, 4);

  const saturation = '03e8';

  const brightness = number2hex(colourBright, 4);

  const lightStr = number2hex(brightValue, 4);

  const musicPowerStr = musicPower ? '01' : '00';

  const musicTypeStr = musiceSetStrMap[musicSet] ?? '00';

  const ringtoneNumber = +ringtone.replace('ringtone_', '');

  const musicStr = number2hex(ringtoneNumber - 1) ?? '01';

  const voiceStr = number2hex(volumeSet);

  return `${powerStr}${lightModeStr}${hueStr}${saturation}${brightness}${lightStr}${musicPowerStr}${musicTypeStr}${musicStr}${voiceStr}`;
};

export const decodeScene = (str: string) => {
  if (!str.length || str.length < 4)
    return {
      setted: false,
      music: 'ringtone_1',
      musicSet: 'nature',
      musicPower: true,
      lightMode: 'color_ligth',
      voice: 100,
      light: 1000,
      colour: 20,
      lampPower: true,
      colourBright: 1000,
    };

  try {
    let i = 0;

    const lampPower = str.slice(i, i + 2);
    i += 2;

    const lampMode = str.slice(i, i + 2);
    i += 2;

    const hue = str.slice(i, i + 4);
    i += 4;

    const saturation = 1000;
    i += 4;

    const brightness = str.slice(i, i + 4);
    i += 4;

    const light = str.slice(i, i + 4);
    i += 4;

    const musicPower = str.slice(i, i + 2);
    i += 2;

    const musicType = str.slice(i, i + 2);
    i += 2;

    const musicOrder = str.slice(i, i + 2);
    i += 2;

    const musicVolume = str.slice(i, i + 2);
    i += 2;

    return {
      music: `ringtone_${hex2Dec(musicOrder) + 1}`,
      musicSet: musiceSetStrMap[musicType] ?? 'nature',
      musicPower: musicPower === '01',
      lightMode: lampModeMap[lampMode],
      voice: hex2Dec(musicVolume),
      light: hex2Dec(light),
      colour: hex2Dec(hue),
      lampPower: !!hex2Dec(lampPower),
      colourBright: hex2Dec(brightness),
    };
  } catch (error) {
    return {
      setted: false,
      music: 'ringtone_1',
      musicSet: 'nature',
      musicPower: true,
      lightMode: 'color_ligth',
      voice: 100,
      light: 1000,
      colour: 20,
      lampPower: true,
      colourBright: 1000,
    };
  }
};

// 判断是否是奇数
export const isOdd = num => {
  return num % 2 !== 0;
};
// 确定数字的位置
export const numPosition = (val, width, border) => {
  const offset = border / 2;
  const all = width + border * 2 * 2;
  const obj = {
    0: { top: offset, left: 0 },
    1: { top: 0, left: offset },
    2: { top: offset, left: 2 * offset + border * 2 + width },
    3: { top: 2 * offset + border * 2 + width, left: offset },
    4: { top: all + offset - border, left: 0 },
    5: { top: (2 * offset + border * 2 + width) * 2, left: offset },
    6: { top: all + offset - border, left: 2 * offset + border * 2 + width },
  };
  return obj[val];
};

// 数字对应的index拼接
export const numToIndex = val => {
  const obj = {
    0: [0, 1, 2, 4, 5, 6],
    1: [2, 6],
    2: [1, 2, 3, 4, 5],
    3: [1, 2, 3, 5, 6],
    4: [0, 2, 3, 6],
    5: [0, 1, 3, 5, 6],
    6: [0, 1, 3, 4, 5, 6],
    7: [1, 2, 6],
    8: [0, 1, 2, 3, 4, 5, 6],
    9: [0, 1, 2, 3, 5, 6],
    10: [3],
  };
  return obj[val];
};

// 格式化当前时间为HH: MM格式
export const formatCurrentTime = (curTime: number, timeMode: string) => {
  let hours = String(Math.floor(curTime / 60)).padStart(2, '0');
  const minutes = String(curTime % 60).padStart(2, '0');

  if (timeMode === '12h') {
    hours = String(+hours[0] % 12).padStart(2, '0');
  }

  return {
    hours,
    minutes,
    period: timeMode === '12h' ? (+hours >= 12 ? ' PM' : ' AM') : '',
  };
};

/**
 * 将秒数转换为小时、分钟和秒的对象格式
 * @param totalSeconds 总秒数
 * @returns 包含小时、分钟、秒的对象
 */
export const formatSecondsToHMS = (
  totalSeconds: number
): { hourText: string; minuteText: string; secondText: string } => {
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const seconds = totalSeconds % 60;

  return {
    hourText: String(hours).padStart(2, '0'),
    minuteText: String(minutes).padStart(2, '0'),
    secondText: String(seconds).padStart(2, '0'),
  };
};
